home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swagd_f.zip / EGAVGA.SWG / 0131_CatMull-Rom spline source.pas < prev    next >
Pascal/Delphi Source File  |  1994-08-25  |  7KB  |  154 lines

  1. {
  2. From: ldeboer@cougar.multiline.com.au (Leon DeBoer)
  3.  
  4. {------------------------------------------------------------------------}
  5. {          Catmull_Rom and BSpline Parametric Spline Program             }
  6. {                                                                        }
  7. {       All source written and devised by Leon de Boer, (c)1994          }
  8. {       E-Mail:   ldeboer@cougar.multiline.com.au                        }
  9. {                                                                        }
  10. {       After many request and talk about spline techniques on the       }
  11. {   internet I decided to break out my favourite spline programs and     }
  12. {   donate to the discussion.                                            }
  13. {                                                                        }
  14. {     Each of splines is produced using it's parametric basis matrix     }
  15. {                                                                        }
  16. {   B-Spline:                                                            }
  17. {              -1   3  -3   1           /                                }
  18. {               3  -6   3   0          /                                 }
  19. {              -3   0   3   0         /  6                               }
  20. {               1   4   1   0        /                                   }
  21. {                                                                        }
  22. {   CatMull-Rom:                                                         }
  23. {              -1   3  -3   1           /                                }
  24. {               2  -5   4  -1          /                                 }
  25. {              -1   0   1   0         /   2                              }
  26. {               0   2   0   0        /                                   }
  27. {                                                                        }
  28. {    The basic differences between the splines:                          }
  29. {                                                                        }
  30. {       B-Splines only passes through the first and last point in the    }
  31. {   list of control points, the other points merely provide degrees of   }
  32. {   influence over parts of the curve (BSpline in green shows this).     }
  33. {                                                                        }
  34. {       Catmull-Rom splines is one of a few splines that actually pass   }
  35. {   through each and every control point the tangent of the curve as     }
  36. {   it passes P1 is the tangent of the slope between P0 and P2 (The      }
  37. {   curve is shown in red)                                               }
  38. {                                                                        }
  39. {       There is another spline type that passes through all the         }
  40. {   control points which was developed by Kochanek and Bartels and if    }
  41. {   anybody knows the basis matrix could they E-Mail to me ASAP.         }
  42. {                                                                        }
  43. {      In the example shown the program produces 5 random points and     }
  44. {   displays the 2 spline as well as the control points. You can alter   }
  45. {   the number of points as well as the drawing resolution via the       }
  46. {   appropriate parameters.                                              }
  47. {------------------------------------------------------------------------}
  48.  
  49. PROGRAM Spline;
  50.  
  51. USES Graph;
  52.  
  53. TYPE
  54.    Point3D = Record
  55.      X, Y, Z: Real;
  56.    End;
  57.  
  58. VAR  CtrlPt: Array [-1..80] Of Point3D;
  59.  
  60. PROCEDURE Spline_Calc (Ap, Bp, Cp, Dp: Point3D; T, D: Real; Var X, Y: Real);
  61. VAR T2, T3: Real;
  62. BEGIN
  63.    T2 := T * T;                                       { Square of t }
  64.    T3 := T2 * T;                                      { Cube of t }
  65.    X := ((Ap.X*T3) + (Bp.X*T2) + (Cp.X*T) + Dp.X)/D;  { Calc x value }
  66.    Y := ((Ap.Y*T3) + (Bp.Y*T2) + (Cp.Y*T) + Dp.Y)/D;  { Calc y value }
  67. END;
  68.  
  69. PROCEDURE BSpline_ComputeCoeffs (N: Integer; Var Ap, Bp, Cp, Dp: Point3D);
  70. BEGIN
  71.    Ap.X := -CtrlPt[N-1].X + 3*CtrlPt[N].X - 3*CtrlPt[N+1].X + CtrlPt[N+2].X;
  72.    Bp.X := 3*CtrlPt[N-1].X - 6*CtrlPt[N].X + 3*CtrlPt[N+1].X;
  73.    Cp.X := -3*CtrlPt[N-1].X + 3*CtrlPt[N+1].X;
  74.    Dp.X := CtrlPt[N-1].X + 4*CtrlPt[N].X + CtrlPt[N+1].X;
  75.    Ap.Y := -CtrlPt[N-1].Y + 3*CtrlPt[N].Y - 3*CtrlPt[N+1].Y + CtrlPt[N+2].Y;
  76.    Bp.Y := 3*CtrlPt[N-1].Y - 6*CtrlPt[N].Y + 3*CtrlPt[N+1].Y;
  77.    Cp.Y := -3*CtrlPt[N-1].Y + 3*CtrlPt[N+1].Y;
  78.    Dp.Y := CtrlPt[N-1].Y + 4*CtrlPt[N].Y + CtrlPt[N+1].Y;
  79. END;
  80.  
  81. PROCEDURE Catmull_Rom_ComputeCoeffs (N: Integer; Var Ap, Bp, Cp, Dp: Point3D);
  82. BEGIN
  83.    Ap.X := -CtrlPt[N-1].X + 3*CtrlPt[N].X - 3*CtrlPt[N+1].X + CtrlPt[N+2].X;
  84.    Bp.X := 2*CtrlPt[N-1].X - 5*CtrlPt[N].X + 4*CtrlPt[N+1].X - CtrlPt[N+2].X;
  85.    Cp.X := -CtrlPt[N-1].X + CtrlPt[N+1].X;
  86.    Dp.X := 2*CtrlPt[N].X;
  87.    Ap.Y := -CtrlPt[N-1].Y + 3*CtrlPt[N].Y - 3*CtrlPt[N+1].Y + CtrlPt[N+2].Y;
  88.    Bp.Y := 2*CtrlPt[N-1].Y - 5*CtrlPt[N].Y + 4*CtrlPt[N+1].Y - CtrlPt[N+2].Y;
  89.    Cp.Y := -CtrlPt[N-1].Y + CtrlPt[N+1].Y;
  90.    Dp.Y := 2*CtrlPt[N].Y;
  91. END;
  92.  
  93. PROCEDURE BSpline (N, Resolution, Colour: Integer);
  94. VAR I, J: Integer; X, Y, Lx, Ly: Real; Ap, Bp, Cp, Dp: Point3D;
  95. BEGIN
  96.    SetColor(Colour);
  97.    CtrlPt[-1] := CtrlPt[1];
  98.    CtrlPt[0] := CtrlPt[1];
  99.    CtrlPt[N+1] := CtrlPt[N];
  100.    CtrlPt[N+2] := CtrlPt[N];
  101.    For I := 0 To N Do Begin
  102.      BSpline_ComputeCoeffs(I, Ap, Bp, Cp, Dp);
  103.      Spline_Calc(Ap, Bp, Cp, Dp, 0, 6, Lx, Ly);
  104.      For J := 1 To Resolution Do Begin
  105.        Spline_Calc(Ap, Bp, Cp, Dp, J/Resolution, 6, X, Y);
  106.        Line(Round(Lx), Round(Ly), Round(X), Round(Y));
  107.        Lx := X; Ly := Y;
  108.      End;
  109.    End;
  110. END;
  111.  
  112. PROCEDURE Catmull_Rom_Spline (N, Resolution, Colour: Integer);
  113. VAR I, J: Integer; X, Y, Lx, Ly: Real; Ap, Bp, Cp, Dp: Point3D;
  114. BEGIN
  115.    SetColor(Colour);
  116.    CtrlPt[0] := CtrlPt[1];
  117.    CtrlPt[N+1] := CtrlPt[N];
  118.    For I := 1 To N-1 Do Begin
  119.      Catmull_Rom_ComputeCoeffs(I, Ap, Bp, Cp, Dp);
  120.      Spline_Calc(Ap, Bp, Cp, Dp, 0, 2, Lx, Ly);
  121.      For J := 1 To Resolution Do Begin
  122.        Spline_Calc(Ap, Bp, Cp, Dp, J/Resolution, 2, X, Y);
  123.        Line(Round(Lx), Round(Ly), Round(X), Round(Y));
  124.        Lx := X; Ly := Y;
  125.      End;
  126.    End;
  127. END;
  128.  
  129. VAR I, J, Res, NumPts: Integer;
  130. BEGIN
  131.    I := Detect;
  132.    InitGraph(I, J, 'e:\bp\bgi');
  133.    I := GetMaxX; J := GetMaxY;
  134.    Randomize;
  135.    CtrlPt[1].X := Random(I); CtrlPt[1].Y := Random(J);
  136.    CtrlPt[2].X := Random(I); CtrlPt[2].Y := Random(J);
  137.    CtrlPt[3].X := Random(I); CtrlPt[3].Y := Random(J);
  138.    CtrlPt[4].X := Random(I); CtrlPt[4].Y := Random(J);
  139.    CtrlPt[5].X := Random(I); CtrlPt[5].Y := Random(J);
  140.    Res := 20;
  141.    NumPts := 5;
  142.    BSpline(NumPts, Res, LightGreen);
  143.    CatMull_Rom_Spline(NumPts, Res, LightRed);
  144.    SetColor(Yellow);
  145.    For I := 1 To NumPts Do Begin
  146.      Line(Round(CtrlPt[I].X-3), Round(CtrlPt[I].Y),
  147.        Round(CtrlPt[I].X+3), Round(CtrlPt[I].Y));
  148.      Line(Round(CtrlPt[I].X), Round(CtrlPt[I].Y-3),
  149.        Round(CtrlPt[I].X), Round(CtrlPt[I].Y+3));
  150.    End;
  151.    ReadLn;
  152.    CloseGraph;
  153. END.
  154.